<?php
/**
 * 生成指定公众号的二维码
 *
 * Author: Zeon
 * Date: 2017/7/21
 * Time: 16:24
 * Created by PhpStorm.
 */
namespace App\Services\OpenWechat;


use App\Exceptions\ApiException;
use App\Services\Utils\ApiChecker;

class QrCode
{
    use ApiChecker;

    const ONE_HOUR_SECONDS = 3600;

    const ONE_DAY_HOURS = 24;

    const DAYS = 6;

    /**
     * 请使用返回的网址生成二维码
     *
     * @param $appid
     * @param string|int $scene_value
     * @param $expire_seconds - default 7 days
     * @param bool $forever
     * @return string
     */
    public static function generateUrl($appid, $scene_value, $expire_seconds = null, $forever = false)
    {
        return self::generate($appid, $scene_value, $expire_seconds, $forever)['url'];
    }

    /**
     * @param $appid
     * @param $scene_value
     * @param null $expire_seconds
     * @param bool $forever
     * @return string
     */
    public static function generateTicket($appid, $scene_value, $expire_seconds = null, $forever = false)
    {
        return self::generate($appid, $scene_value, $expire_seconds, $forever)['ticket'];
    }

    /**
     * @example
     *      =>
     * @param $appid
     * @param $scene_value
     * @param null $expire_seconds
     * @param bool $forever
     * @return array
     */
    public static function generate($appid, $scene_value, $expire_seconds = null, $forever = false)
    {
        $qrcode = (new AppFactory())->authorizerApp($appid)->qrcode;

        /**
         * @see Mock::qrCode() - 成功返回值
         * @see Mock::qrCodeErr() - 错误返回值
         */
        $result = $forever
            ? $qrcode->forever($scene_value)
            : $qrcode->temporary($scene_value, $expire_seconds);

        return $result;
    }

    /**
     * 使用 generateTicket 生成的 ticket 直接返回微信生成二维码的图片地址
     * @see generateTicket()
     *
     * @param $appid
     * @param string $ticket
     * @return string
     */
    public static function ticketToQrCodeUrl($appid, $ticket)
    {
        return (new AppFactory())->authorizerApp($appid)->qrcode->url($ticket);
    }


    /**
     * 生成临时二维码的 URL
     *
     * @param $appid
     * @param $event_key
     * @param null $alive_second
     *
     * @return string
     * @throws ApiException
     */
    public function tempUrl($appid, $event_key, $alive_second = null)
    {
        $qr_code = (new AppFactory())->authorizerApp($appid)->qrcode;


        $ticket = $qr_code->temporary(
            $event_key,
            $alive_second ?: $this->defaultTempAliveSeconds()
        );

        if ( isset($ticket['errcode'])) throw New ApiException($ticket['errcode'], $ticket['errmsg']);

        $url = $qr_code->url($ticket['ticket']);

        return $url;
    }

    /**
     * @return int
     */
    public function defaultTempAliveSeconds()
    {
        return self::DAYS * self::ONE_DAY_HOURS * self::ONE_HOUR_SECONDS;
    }

    /**
     * @param array $qr_result
     * @throws \Exception
     */
    public function checkQrResult(array $qr_result): void
    {
        if (! isset($qr_result['errcode'])) {
            return;
        }

        // customize error response by err code
        switch ($qr_result['errcode']) {
            case WechatErrorCode::API_UNAUTHORIZED :
                $qr_result['errmsg'] = trans('wechat.error.qr_code_api_unauthorized');
                break;
            default :
                break;
        }

        $this->checkFailed($qr_result['errmsg'], $qr_result['errcode']);
    }
}